<template>
  <div class="student">
    <span>{{ fruits.fruit }}的价格{{ fruits.price }}</span>
    <br />
    <button @click="changePrice">修改{{ fruits.fruit }}的价格</button>
    <button @click="changeFruit">修改{{ fruits.fruit }}的品种</button>
    <br />
    <span>{{ cars.car }}的价格{{ cars.price }}</span>
    <br />
    <button @click="changeCar">修改{{ cars.car }}</button>
    <br />
    <br />
    <br />
    <h2>游戏列表</h2>
    <ul>
      <li v-for="item in games" :key="item.id">{{ item.name }}</li>
    </ul>
    <button @click="changeName">修改游戏名字</button>
  </div>
</template>

<script lang="ts" setup>
import { reactive, ref } from 'vue'
// reactive 也是响应式数据，无论嵌套多深，都可以响应
// reactive写法：只能定义对象类型的数据,proxy响应式对象
// const fruits = reactive({ fruit: '芒果', price: 10 })
// const games = reactive([
//   { name: '王荣荣耀', id: 1 },
//   { name: '幻兽帕鲁', id: 2 },
//   { name: '我的世界', id: 3 }
// ])

// function changePrice() {
//   fruits.price += 10
// console.log('fruits.price', fruits.price)

// }

// function changeName() {
//   games[0].name = '美味的披萨'
// console.log('123', games.value[0])
// }

// ref:能定义基本类型的数据，也能定义对象类型的数据
// ref定义对象，打印出来看到他是RefImpl对象，打开value会发现，他指向的还是一个proxy的响应式数据，所以当用ref定义对象的时候，其实还是借助的reactive
// ref可以使用 volar 插件自动添加
const fruits = reactive({ fruit: '芒果', price: 10 })
const cars = ref({ car: '奔驰', price: 100 })
const games = ref([
  { name: '王荣荣耀', id: 1 },
  { name: '幻兽帕鲁', id: 2 },
  { name: '我的世界', id: 3 }
])

function changePrice() {
  fruits.price += 10
  console.log('123', fruits)
}

// 如果想要整体修改 reactive 定义的响应式对象，需要用到Object.assign
function changeFruit() {
  // Object.assign（原数据，修改后的数据）
  Object.assign(fruits, { fruit: '榴莲', price: 20 })
  console.log('123', fruits)
}

// 如果想要整体修改 ref 定义的响应式对象，可以直接修改
function changeCar() {
  cars.value = { car: '宝马', price: 200 }
}

function changeName() {
  console.log(
    '%c games[0].value',
    'background-color:red;color:#fff;padding:5px;border-radius:5px',
    games.value[0]
  )
  games.value[0].name = '美味的披萨'
}

// ref 和 reactive 的区别
// 1. ref 创建的变量，必须使用 .value（可以使用 volar 插件自动添加 .value）
// 2. reactive 重新分配一个新对象，会失去响应式，可以使用Object.assign（原数据，修改后的数据）去替换
// 使用规则：
// 1.若是使用基本数据类型的响应式数据，必须使用 ref
// 2.若是需要一个响应式对象层级不深， ref / reactive 都可以，若是层级较深，推荐使用reactive
</script>

<style scoped>
.student {
  width: 100%;
  height: 500px;
  background-color: aqua;
}
</style>
